//
// Created by 86134 on 2024/1/18.
//

#include "Connection.hpp"
#include "../base/Defind.hpp"
#include "Socket.hpp"
#include <sys/epoll.h>

/*-----------------------------------------------
 * 
 * Connection Api Immpelement
 * 
 * ----------------------------------------------
*/
using namespace DBServer::Socket;

Connection::Connection() {
    // configure everything to wait for creating a socket
    this->tcp_buffer = new TcpBuffer();
    // create a connection without socket fd
    this->socket_status = UNUSE;
    // alloc the memory for the std::function<void(void)> pointer
    write_cb = [this](int fd){
        return this->tcp_buffer->push(fd);
    };
    read_cb = [this](int fd, int& ret){
        return this->tcp_buffer->read(fd, ret);
    };
    // alloc the memory for SocketInfo struct
    socket_info = new SocketInfo{};
}

Connection::~Connection() {
    if (socket_info) delete socket_info;
    if (tcp_buffer) delete tcp_buffer;
}

int 
Connection::create_socket() {
    // in the parent class achieve for server
    return socket_server(*this);
}

int 
Connection::close_socket() {
    return socket_close(*this);
}

int 
Connection::set_so_reuse() {
    return socket_set_reuse(*this);
}

int 
Connection::set_so_unblock() {
    return socket_set_unblock(*this);
}

void 
Connection::set_socket_fd(int fd) {
    socket_fd = fd;
}

void 
Connection::set_logic_cb(std::function<std::string(std::string&&)> func) {
    logic_func = func;
}

void
Connection::set_epoll_fd(int fd) {
    epoll_fd = fd;
}

void
Connection::set_socket_status(int status) {
    socket_status = status;
}

void
Connection::set_socket_info(std::string&& ip, int port) {
    socket_info->port = port;
    socket_info->ip = std::move(ip);
}

std::unique_ptr<DBServer::Socket::SocketInfo>
Connection::get_socket_info() {
    std::unique_ptr<DBServer::Socket::SocketInfo> si(
        new DBServer::Socket::SocketInfo(*socket_info));
    return si;
}

int 
Connection::get_socket_fd() {
    return socket_fd;
}

int
Connection::get_socket_status() {
    return socket_status;
}

void
Connection::set_epoll_event() {
    event.data.fd = socket_fd;
    // default event is read event
    event.events |= EPOLLIN;
}

struct epoll_event*
Connection::get_epoll_event() {
    return &event;
}

TcpBuffer*
Connection::get_buff() {
    return tcp_buffer;
}


auto Connection::get_read_cb() -> std::function<std::vector<std::shared_ptr<Request>>(int, int&)> {
    return read_cb;
}

auto Connection::get_logic_cb() -> std::function<std::string(std::string&&)> {
    return logic_func;
}

auto Connection::get_write_cb() -> std::function<int(int)> {
    return write_cb;
}

/*  */
/*  */
int
DBServer::Socket::ServerConn::create_socket(int listen_fd) {
    DBServer::Socket::socket_accept(*this, listen_fd);
    return 0;
}


int
DBServer::Socket::ClientConn::create_socket() {
    socket_client(*this);
    return 0;
}

int
DBServer::Socket::Listener::create_socket() {
    DBServer::Socket::socket_server(*this);
    return 0;
}